package com.beidouapp.security.mvc;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.beidouapp.domain.pojo.Resource;
import com.beidouapp.domain.pojo.Role;
import com.beidouapp.security.model.MenuVo;
import com.beidouapp.security.model.ReturnDataInfo;
import com.beidouapp.security.model.SessionUser;
import com.beidouapp.security.model.ui.UIResource;
import com.beidouapp.security.utils.DscpCommUtils;
import com.beidouapp.service.ResourceService;
import com.beidouapp.service.RoleService;

@Controller
@RequestMapping(value = "/resource")
public class ResourceController {
    private static final Logger logger = LoggerFactory.getLogger(ResourceController.class);

    @Autowired
    private ResourceService resourceService;

    @Autowired
    private RoleService roleService;

    private static Map<String, Resource> resourceCache = null;

    private static Map<Long, String> resourceCacheIdMap = null;

    /**
     * 授权保存
     *
     * @param session
     * @param request
     * @param resources
     * @param roleId
     * @return
     */
    @RequestMapping(value = "/grantResource2Role/{roleId}", method = RequestMethod.POST, headers = "Content-Type=application/json")
    public
    @ResponseBody
    ReturnDataInfo<String> grantResource2Role(HttpSession session, HttpServletRequest request, @RequestBody List<LinkedHashMap<String, String>> resources, @PathVariable Long roleId) {
        try {
            Role role = roleService.getRoleById(roleId);
            if (role == null) {
                throw new Exception("此角色不存在或已被删除");
            }

            List<Resource> hold_resources = resourceService.findRoleResourcesByRoleId(roleId);
            List<String> addCodeList = new ArrayList<String>();
            Set<Long> addIdList = new TreeSet<Long>();
            Set<Long> delIdList = new TreeSet<Long>();
            for (LinkedHashMap<String, String> resource : resources) {
                String code = resource.get("code");
                if (code != null) {
                    addCodeList.add(code);
                    Resource resourcetmp = getResourceCache().get(code);
                    if (resourcetmp != null) {
                        addIdList.add(resourcetmp.getId());
                        if (resourcetmp.getParentId() != null) {
                            addIdList.add(resourcetmp.getParentId());
                        }
                    }
                }
            }

            for (Resource resuource : hold_resources) {
                if (!addCodeList.contains(resuource.getCode())) {
                    delIdList.add(resuource.getId());
                } else {
                    addIdList.remove(resuource.getId());
                }
            }
            resourceService.grantResources(roleId, addIdList, delIdList);
            return ReturnDataInfo.createSuccessfulSingleExecuteResult(null);
        } catch (Exception ex) {
            return ReturnDataInfo.createFailedExecuteResult(ex.getMessage());
        }
    }


    /**
     * 加载菜单
     *
     * @param session
     * @return
     */
    @RequestMapping(value = "/loadMenu", method = RequestMethod.GET)
    public
    @ResponseBody
    ReturnDataInfo<MenuVo> getMenuList(HttpSession session) {
        List<Resource> resources = new ArrayList<Resource>();
        List<String> codes = DscpCommUtils.getResource(session);
        SessionUser sessionUser = DscpCommUtils.getSessionUser(session);
        Long roleGroupId = sessionUser.getRoleGroupId();
        if (codes != null) {
            List<Resource> resourcestmp = DscpCommUtils.getResourcesByCodes(codes, getResourceCache());
            for(Resource rtmp : resourcestmp){
            	if(rtmp.getRoleGroupId().longValue()==roleGroupId.longValue()){
            		resources.add(rtmp);
            	}
            }
        }
        List<MenuVo> topmenus = DscpCommUtils.assembleMenu(resources);
        return ReturnDataInfo.createSuccessfulExecuteResults(topmenus);
    }
    


    //---------------------------------------------------

    //@RequestMapping(value = "/list/{roleId}", method = RequestMethod.GET)
    //public
    //@ResponseBody
    //ReturnDataInfo<UIResource> listResource(HttpSession session, @PathVariable Integer roleId) {
    //    try {
    //        Role role = roleService.getRoleById(roleId);
    //        if (role == null) {
    //            logger.error("roleId={}的角色不存在或已被删除", roleId);
    //            throw new Exception("此角色不存在或已被删除");
    //        }
    //        List<Resource> all_resources = new ArrayList<Resource>();
    //        if (!DscpCommUtils.isSupperAdmin(session)) {
    //            SessionUser sessionUser = DscpCommUtils.getSessionUser(session);
    //            // 用户只能将自己有的资源授给角色，并且这个角色是属于他的组织
    //            List<Role> roles = roleExtService.findRoleByOragnization(Integer.valueOf(sessionUser.getOrgId()));
    //            boolean isRoleExist = false;
    //            for (Role roleTmp : roles) {
    //                if (role.getId().intValue() == roleTmp.getId().intValue()) {
    //                    isRoleExist = true;
    //                    break;
    //                }
    //            }
    //            if (!isRoleExist) {
    //                throw new Exception("你没有权限给此角色授权");
    //            }
    //            List<String> codes = DscpCommUtils.getResource(session);
    //            for (Resource resource : getResourceCache().values()) {
    //                String code = resource.getCode();
    //                if (codes.contains(code)) {
    //                    all_resources.add(resource);
    //                }
    //            }
    //        } else {
    //            for (Resource resource : getResourceCache().values()) {
    //                if (role.getStatus() != null && role.getStatus().equals(String.valueOf(RoleStatus.ADMIN_ROLE
    //                        .getStatus()))) {
    //                    if (resource.getAppShortName().equals("web")) {
    //                        all_resources.add(resource);
    //                    }
    //                } else {
    //                    if (resource.getAppShortName().equals("web_new")) {
    //                        all_resources.add(resource);
    //                    }
    //                }
    //            }
    //        }
    //        List<Resource> hold_resources = new ArrayList<Resource>();
    //        if (role.getStatus() != null && role.getStatus().equals(String.valueOf(RoleStatus.ADMIN_ROLE.getStatus()))) {
    //            hold_resources = resourceService.findResourceByAppAndRole("web", role.getCode());
    //        } else {
    //            hold_resources = resourceService.findResourceByAppAndRole("web_new", role.getCode());
    //        }
    //
    //        List<UIResource> uiResources = new ArrayList<UIResource>();
    //        for (Resource resource : all_resources) {
    //            UIResource uiResource = new UIResource();
    //            uiResource.setId(resource.getId());
    //            uiResource.setCode(resource.getCode());
    //            uiResource.setName(resource.getName());
    //            // uiResource.setParentName(parentName);
    //            for (Resource hold_resource : hold_resources) {
    //                if (resource.getId().intValue() == hold_resource.getId().intValue()) {
    //                    uiResource.setIsChecked(true);
    //                    break;
    //                }
    //            }
    //            if (resource.getParentId() != null) {
    //                String code = getResourceCacheIdMap().get(resource.getParentId());
    //                if (code != null) {
    //                    Resource paremtResource = getResourceCache().get(code);
    //                    if (paremtResource != null) {
    //                        uiResource.setParentName(paremtResource.getName());
    //                        uiResource.setParentCode(code);
    //                    }
    //                }
    //            }
    //            uiResources.add(uiResource);
    //        }
    //        return ReturnDataInfo.createSuccessfulExecuteResults(uiResources);
    //    } catch (Exception ex) {
    //        return ReturnDataInfo.createFailedExecuteResult(ex.getMessage());
    //    }
    //}


    //----------------------------


    private synchronized void cacheResource() {
        if (resourceCache == null) {
            resourceCache = new LinkedHashMap<String, Resource>();
            resourceCacheIdMap = new LinkedHashMap<Long, String>();

            List<Resource> resources = resourceService.findAllResource();
            for (Resource resource : resources) {
                resourceCache.put(resource.getCode(), resource);
                resourceCacheIdMap.put(resource.getId(), resource.getCode());
            }
        }
    }

    /**
     * 角色授权时获取资源列表
     *
     * @param session
     * @param roleId
     * @return
     */
    @RequestMapping(value = "/list2Role/{roleId}", method = RequestMethod.GET)
    public
    @ResponseBody
    ReturnDataInfo<UIResource> listResource2Group(HttpSession session, @PathVariable Long roleId) {
        try {
            Role role = roleService.getRoleById(roleId);
            if (role == null) {
                throw new Exception("此角色不存在或已被删除");
            }
            List<Resource> all_resources = new ArrayList<Resource>(getResourceCache().values());

            List<Resource> hold_resources = resourceService.findRoleResourcesByRoleId(roleId);

            List<UIResource> uiResources = new ArrayList<UIResource>();
            for (Resource resource : all_resources) {
                if (role.getRoleGroupId() != resource.getRoleGroupId()) continue;
                UIResource uiResource = new UIResource();
                uiResource.setId(resource.getId());
                uiResource.setCode(resource.getCode());
                uiResource.setName(resource.getName());
                for (Resource hold_resource : hold_resources) {
                    if (resource.getId().intValue() == hold_resource.getId().intValue()) {
                        uiResource.setIsChecked(true);
                        break;
                    }
                }
                if (resource.getParentId() != null) {
                    String code = getResourceCacheIdMap().get(resource.getParentId());
                    if (code != null) {
                        Resource paremtResource = getResourceCache().get(code);
                        if (paremtResource != null) {
                            uiResource.setParentName(paremtResource.getName());
                            uiResource.setParentCode(code);
                        }
                    }
                }
                uiResources.add(uiResource);
            }
            return ReturnDataInfo.createSuccessfulExecuteResults(uiResources);
        } catch (Exception ex) {
            return ReturnDataInfo.createFailedExecuteResult(ex.getMessage());
        }
    }


    private Map<String, Resource> getResourceCache() {
        if (resourceCache == null) {
            this.cacheResource();
        }
        return resourceCache;
    }

    private Map<Long, String> getResourceCacheIdMap() {
        if (resourceCacheIdMap == null) {
            this.cacheResource();
        }
        return resourceCacheIdMap;
    }

}
